﻿using Abp.BackgroundJobs;
using Abp.Domain.Repositories;
using Abp.Domain.Services;
using Abp.Domain.Uow;
using Mt.Site.Core.BackGroundJobs;
using Mt.Site.Core.BackGroundJobs.ContentManagement;
using Mt.Site.Core.ContentManagement.Entities;
using Mt.Site.Core.StaticPages;
using Mt.Site.Core.Synchronization.Data;
using Mt.Site.Core.Synchronization.Storage;
using System;
using System.Threading.Tasks;

namespace Mt.Site.Core.Synchronization.ContentManagement
{
    public class ContentManualSyncManager : DomainService, IContentManualSyncManager
    {
        private readonly IRepository<Content, Guid> _contentRepository;

        private readonly IContentDataSoreManager _contentDataSoreManager;

        public readonly ISynchronizationHelper _synchronizationHelper;

        private readonly IBackgroundJobManager _backgroundJobManager;

        private readonly IFileObjectManualSyncManager _fileObjectManualSyncManager;

        private readonly IStaticPageHelper _staticPageHelper;

        public ContentManualSyncManager(
                IRepository<Content, Guid> contentRepository,
                IContentDataSoreManager contentDataSoreManager,
                ISynchronizationHelper synchronizationHelper,
                IBackgroundJobManager backgroundJobManager,
                IFileObjectManualSyncManager fileObjectManualSyncManager,
                IStaticPageHelper staticPageHelper)
        {
            _contentRepository = contentRepository;
            _contentDataSoreManager = contentDataSoreManager;
            _synchronizationHelper = synchronizationHelper;
            _backgroundJobManager = backgroundJobManager;
            _fileObjectManualSyncManager = fileObjectManualSyncManager;
            _staticPageHelper = staticPageHelper;
        }

        [UnitOfWork]
        public Guid CreateOrUpdateContentManualSync(CreateOrUpdateSynchorizeStore input)
        {
            if (!_synchronizationHelper.ShouldSynchronize(input.ToTenantId))
            {
                return Guid.Empty;
            }

            using (CurrentUnitOfWork.DisableFilter(
                AbpDataFilters.MayHaveTenant,
                AbpDataFilters.MustHaveTenant,
                MtSiteConsts.AbpDataFilters.MustHaveLanguage,
                AbpDataFilters.SoftDelete))
            {
                var fromEntity = _contentRepository.FirstOrDefault(item=>item.Id == input.Id && item.IsDeleted == false);
                if (fromEntity == null)
                {
                    return Guid.Empty;
                }

                var toEntity = _contentRepository.FirstOrDefault(
                        item => item.SourceID == input.Id && item.Language == input.TargetLanguage && item.TenantId == input.ToTenantId);

                var toNewsId = Guid.Empty;
                if (toEntity == null)
                {
                    toNewsId = _contentDataSoreManager.CreateContentSync(fromEntity,
                                new DataProcessingStore
                                {
                                    TargetLanguage = input.TargetLanguage,
                                    ToTenantId = input.ToTenantId
                                });
                    input.OptionType = OptionType.Create;
                }
                else
                {
                    toNewsId = _contentDataSoreManager.UpdateContentSync(toEntity, fromEntity);
                    input.OptionType = OptionType.Update;
                }

                if (toNewsId != Guid.Empty)
                {
                    var entity = _contentRepository.FirstOrDefault(toNewsId);
                    if (entity != null)
                    {
                        //不是新建
                        _staticPageHelper.DeleteListAndDetailPage(entity.TenantId, entity.Language, entity.MenuId, entity.AuxiliaryId);
                        _staticPageHelper.DeleteStaticPage(entity.TenantId, entity.Language, 0);
                    }
                    CreateOrUpdateFileInfoSync(input, toNewsId, fromEntity.TenantId, fromEntity.Language, fromEntity.Id);
                    _synchronizationHelper.SyncRouteStr(input.Id, toNewsId, input.ToTenantId, input.TargetLanguage);
                    _backgroundJobManager.Enqueue<SynchorizationWholeContentJob, BaseAndMenuIdArgs>(
                            new BaseAndMenuIdArgs
                            {
                                FromLanguage = input.TargetLanguage,
                                FromTenantId = input.ToTenantId,
                                Id = toNewsId,
                                MenuId = fromEntity.MenuId,
                                OperateType = input.OptionType
                            });
                }
                return toNewsId;
            }
        }

        [UnitOfWork]
        public async Task<Guid> CreateOrUpdateContentAutoSync(CreateOrUpdateSynchorizeStore input)
        {
            using (CurrentUnitOfWork.DisableFilter(
                AbpDataFilters.MayHaveTenant,
                AbpDataFilters.MustHaveTenant,
                MtSiteConsts.AbpDataFilters.MustHaveLanguage,
                AbpDataFilters.SoftDelete))
            {
                var notifyArgs = new NoticeArgs();

                try
                {
                    var syncInfo = ContentSyncHelper.CheckDataStatusAndSyncForAutoSync(
                        _contentRepository, _synchronizationHelper, _contentDataSoreManager, _staticPageHelper,
                        input.ToTenantId, input.TargetLanguage, input.Id, notifyArgs, true);

                    notifyArgs.Type = input.OptionType;

                    if (syncInfo != null && syncInfo.ToId != Guid.Empty)
                    {
                        CreateOrUpdateFileInfoSync(input, syncInfo.ToId, syncInfo.FromTenantId, syncInfo.FromLanguage, input.Id);
                        await _synchronizationHelper.SendNoticeForSuccessAsync(notifyArgs);
                        _synchronizationHelper.SyncRouteStr(input.Id, syncInfo.ToId, input.ToTenantId, input.TargetLanguage);
                        return syncInfo.ToId;
                    }
                    return Guid.Empty;
                }
                catch (Exception)
                {
                    if (notifyArgs.FromId != Guid.Empty)
                    {
                        await _synchronizationHelper.SendNoticeForFailAsync(notifyArgs);
                    }
                    throw;
                }
            }
        }


        private void CreateOrUpdateFileInfoSync(CreateOrUpdateSynchorizeStore input, Guid toContentId, int fromTenantId, string fromLanguage, Guid fromContentId)
        {
            _fileObjectManualSyncManager.CreateOrUpdateFileObjectManualSync(
                    new FileObjectSyncStore
                    {
                        FromContenId = fromContentId,
                        FromLanguage = fromLanguage,
                        FromTenantId = fromTenantId,
                        ToContentId = toContentId,
                        ToLanguage = input.TargetLanguage,
                        ToTenantId = input.ToTenantId
                    });
        }
    }
}
